/******************************************************************
*
*	CyberHTTP for Java
*
*	Copyright (C) Satoshi Konno 2002
*
*	File: HTTPHeader.java
*
*	Revision;
*
*	11/19/02
*		- first revision.
*	
******************************************************************/

package com.cidero.http;

import java.io.IOException;
import java.io.LineNumberReader;
import java.io.StringReader;
import java.util.logging.Logger;

/**
 *  Class to handle HTTP header lines of the form:
 *
 *    <name>: <value>
 */
public class HTTPHeader 
{
  private static Logger logger = Logger.getLogger("com.cidero.http");

	private String name;
	private String value;

	public HTTPHeader(String name, String value)
	{
		setName(name);
		setValue(value);
	}

	public HTTPHeader(String lineStr)
	{
		setName("");
		setValue("");

		if (lineStr == null)
			return;

		int colonIdx = lineStr.indexOf(':');
		if (colonIdx < 0)
			return;

		String name = new String(lineStr.getBytes(), 0, colonIdx);				
		String value = new String(lineStr.getBytes(), colonIdx+1,
                              lineStr.length()-colonIdx-1);				
		setName(name.trim());
		setValue(value.trim());
	}

	////////////////////////////////////////////////
	//	Member
	////////////////////////////////////////////////
	
	public void setName(String name)
	{
		this.name = name;
	}
		
	public void setValue(String value)
	{
		this.value = value;
	}

	public String getName()
	{
		return name;
	}

	public String getValue()
	{
		return value;
	}

	public boolean hasName()
	{
		if (name == null ||  name.length() <= 0)
			return false;
		return true;
	}
	
	////////////////////////////////////////////////
	//	static methods
	////////////////////////////////////////////////
	
  /**
   *  Get value for a header with the specified name. Uses a reader 
   *  object, so this routine is parsing the raw HTTP data. 
   *  TODO: What is this routine used for? Is it needed? This routine
   *  and the one below do a lot of work that could probably be avoided
   *   
   *
   *  @return  Returns value field of header with given name, or the 
   *           empty string if no header with that name exists
   */
	public final static String getValue(LineNumberReader reader, String name)
	{
		String bigName = name.toUpperCase();

		try {
			String lineStr = reader.readLine();

			while (lineStr != null && lineStr.length() > 0 ) {
 
				HTTPHeader header = new HTTPHeader(lineStr);
				if (header.hasName() == false) {
					 lineStr = reader.readLine();
					continue;
				}
				String bigLineHeaderName = header.getName().toUpperCase();
				if (bigLineHeaderName.startsWith(bigName) == false) {
					 lineStr = reader.readLine();
					 continue;
				}
				return header.getValue();
			}
		}
		catch (IOException e) {
      logger.warning("IOException looking for header with name '" + 
                     name + "'");
			return "";
		}

		return "";
	}

	public final static String getValue(String data, String name)
	{
		StringReader strReader = new StringReader(data);
		LineNumberReader lineReader = new LineNumberReader(strReader);
		return getValue(lineReader, name);
	}

	public final static String getValue(byte[] data, String name)
	{
		return getValue(new String(data), name);
	}

	public final static int getIntegerValue(String data, String name)
	{
		try {
			return Integer.parseInt(getValue(data, name));
		}
		catch (NumberFormatException e) {
      logger.warning("Integer parse error for string '" + data + "' (returning 0)");
			return 0;
		}
	}

	public final static int getIntegerValue(byte[] data, String name)
	{
		try {
			return Integer.parseInt(getValue(data, name));
		}
		catch (NumberFormatException e) {
      logger.warning("Integer parse error for string '" + data + "' (returning 0)");
			return 0;
		}
	}

  public String toString()
  {
    StringBuffer buf = new StringBuffer();
    buf.append(name);
    buf.append(": ");
    buf.append(value);
    return buf.toString();
    
  }
  
}
